﻿using CommonLib.Util;

namespace DB2.Read;

public class SqlLineRead
{

    private readonly List<string> list;

    private int idx = 0;

    public SqlLineRead()
    {
        list = [];
    }

    public bool HasNext => idx < list.Count;

    public string Next => list[idx++];


    public void Read(List<string> Lines)
    {
        for (int i = 0; i < Lines.Count; i++)
        {
            var line = Lines[i];
            if (line.StartsWith("--"))
            {
                list.Add(line);
                continue;
            }
            if (line.StartsWith("/*"))
            {
                var sub = new List<string>() { line };
                while (!sub[^1].EndsWith("*/"))
                {
                    sub.Add(Lines[++i]);
                }
                list.Add(string.Join("÷", sub));
                continue;
            }
            if (line.StartsWith("IF ") || line.StartsWith("IF("))
            {
                var sub = new List<string>() { line };
                int begin = 1;
                int end = 0;
                while (begin != end)
                {
                    var next = Lines[++i];
                    if (next.StartsWith("IF ") || next.StartsWith("IF(")) begin++;
                    if (next.StartsWith("END IF")) end++;
                    sub.Add(next);
                }
                list.Add(string.Join("÷", sub));
                continue;
            }
            if (line.StartsWith("LOOP") || line.StartsWith("WHILE")
                || line.StartsWith("FOR "))
            {
                var sub = new List<string>() { line };
                int begin = 1;
                int end = 0;
                while (begin != end)
                {
                    var next = Lines[++i];
                    if (next.StartsWith("LOOP")) begin++;
                    if (next.StartsWith("WHILE")) begin++;
                    if (next.StartsWith("FOR ")) begin++;
                    if (next.StartsWith("END LOOP")) end++;
                    sub.Add(next);
                }
                list.Add(string.Join("÷", sub));
                continue;
            }

            if (line.StartsWith("MERGE") || line.StartsWith("SELECT,")
                || line.StartsWith("UPDATE,") || line.StartsWith("INSERT,")
                || line.StartsWith("DELETE,"))
            {
                var sub = new List<string>() { line };
                while (!sub[^1].RealSql().EndsWith(";"))
                {
                    sub.Add(Lines[++i]);
                }
                list.Add(string.Join("÷", sub));
                continue;
            }

            if (line.StartsWith("CREATE OR REPLACE") || line.StartsWith("FUNCTION")
                || line.StartsWith("PROCEDURE"))
            {
                var sub = new List<string>() { line };
                int begin = 0;
                int end = 0;
                while (begin == 0 || begin != end)
                {
                    if (i == Lines.Count - 1) break;
                    var next = Lines[++i];
                    sub.Add(next);
                    if (next.StartsWith("BEGIN")) begin++;
                    if (next.StartsWith("END IF")) continue;
                    if (next.StartsWith("END ") || next.StartsWith("END;")) end++;
                }
                list.Add(string.Join("÷", sub));
                continue;
            }
            list.Add(line);
        }
    }
}
